package com.starsray.dynamic.ds.provider;

import com.baomidou.dynamic.datasource.provider.AbstractJdbcDataSourceProvider;
import com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.starsray.dynamic.ds.config.DatasourceConfig;
import com.starsray.dynamic.ds.util.SQLUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import javax.annotation.Resource;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;

/**
 * 本地数据源提供者
 *
 * @author starsray
 * @date 2021/11/16
 */
@Primary
@Configuration
public class LocalDatasourceProvider {

    /**
     * 数据源配置
     */
    @Resource
    private DatasourceConfig datasourceConfig;

    /**
     * 动态数据源jdbc提供者
     *
     * @return {@link DynamicDataSourceProvider}
     */
    @Bean
    public DynamicDataSourceProvider jdbcDynamicDataSourceProvider() {
        return new AbstractJdbcDataSourceProvider(datasourceConfig.getDriverClassName(), datasourceConfig.getUrl(), datasourceConfig.getUsername(), datasourceConfig.getPassword()) {
            /**
             * 执行支撑
             *
             * @param statement 声明
             * @return {@link Map}<{@link String}, {@link DataSourceProperty}>
             */
            @Override
            protected Map<String, DataSourceProperty> executeStmt(Statement statement) {
                Map<String, DataSourceProperty> dataSourcePropertiesMap = null;
                ResultSet rs = null;
                try {
                    dataSourcePropertiesMap = new HashMap<>();
                    String createSql = SQLUtils.createTable();
                    statement.executeUpdate(createSql);
                    rs = statement.executeQuery(SQLUtils.selectDs());
                    while (rs.next()) {
                        String name = rs.getString("pool_name");
                        DataSourceProperty property = new DataSourceProperty();
                        property.setDriverClassName(rs.getString("driver_class_name"));
                        property.setUrl(rs.getString("url"));
                        property.setUsername(rs.getString("username"));
                        property.setPassword(rs.getString("password"));
                        dataSourcePropertiesMap.put(name, property);
                    }
                    if (dataSourcePropertiesMap.size() == 0) {
                        statement.execute(SQLUtils.primaryDs(datasourceConfig));
                        DataSourceProperty dataSourceProperty = new DataSourceProperty();
                        dataSourceProperty.setDriverClassName(datasourceConfig.getDriverClassName());
                        dataSourceProperty.setUrl(datasourceConfig.getUrl());
                        dataSourceProperty.setUsername(datasourceConfig.getUsername());
                        dataSourceProperty.setPassword(datasourceConfig.getPassword());
                        dataSourcePropertiesMap.put(datasourceConfig.getPrimary(), dataSourceProperty);
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (rs != null) {
                            rs.close();
                        }
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                    try {
                        statement.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                return dataSourcePropertiesMap;
            }
        };
    }
}
